#include <network.h>
using namespace engine;

const char* IP = "192.168.1.222";
uint16 PORT = 18000;

uint64 freq = 0;

uint32 getTime()
{
#ifdef WIN32
	LARGE_INTEGER v;  
    
    QueryPerformanceCounter(&v); 

	return 1000 * v.QuadPart / freq;

#else
    struct timeval v;
    gettimeofday(&v, NULL);
    return v.tv_sec * 1000 + v.tv_usec / 1000;
#endif
}

class MyClient : public NetworkClientListener
{
public:
	MyClient()
	{
		mClient = new NetworkClient();
		mClient->addListener(this);
		mClient->connect(IP, PORT);

		mTime = 0;
		mCount = 0;
		mMax = 0;
		mMin = -1;
		mPrint = 0;
	}

	~MyClient()
	{
		SAFE_DELETE(mClient);
	}

	NetworkClient* getClient()
	{
		return mClient;
	}

	virtual void onConnected()
	{
		printf("connected\n");

		mPrint = getTime() - rand() % 1000;

		NetworkStream& s = mClient->beginStream();
		s.writeUInt32(getTime());
		String str;
		str.resize(100);
		s.writeString(str);
		mClient->sendStream(s);
	}

	virtual void onConnectFailed()
	{
		printf("connect failed\n");
		mClient->connect(IP, PORT);
	}

	virtual void onDisconnected()
	{
		printf("disconnected\n");
		mClient->connect(IP, PORT);
	}

	virtual void onMessage(NetworkStream& stream)
	{
		uint32 ping = getTime() - stream.readUInt32();

		if (ping > mMax)
			mMax = ping;

		if (ping < mMin)
			mMin = ping;

		if (getTime() - mPrint > 1000)
		{
			mPrint = getTime();

			uint32 avg = mCount > 0 ? mTime / mCount : 0;

			printf("ping %d avg %d, min %d, max %d\n", ping, avg, mMin, mMax);
		}

		mTime += ping;
		mCount++;

		NetworkStream& s = mClient->beginStream();
		s.writeUInt32(getTime());
		String str;
		str.resize(rand() % 60000);
		s.writeString(str);
		mClient->sendStream(s);
	}

	NetworkClient* mClient;
	uint64 mTime;
	uint64 mCount;
	uint32 mMax;
	uint32 mMin;
	uint32 mPrint;
};


int main()
{
#ifdef WIN32
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);

	LARGE_INTEGER v;
    QueryPerformanceFrequency(&v);
	freq = v.QuadPart;

#else
	struct sigaction sa;
    sa.sa_handler = SIG_IGN;
    sigaction(SIGPIPE, &sa, 0);
#endif

	const int CLIENT_COUNT = 100;

	MyClient* c = new MyClient[CLIENT_COUNT];

	uint32 t = getTime();

	while (true)
	{
		uint32 now = getTime();

		if (now - t < 1)
		{
			Thread::sleep(1);
		}
		else
		{
			t = now;

			for (int i = 0; i < CLIENT_COUNT; i++)
			{
				c[i].getClient()->handleMessages();
			}
		}
	}
}
